"""
权限类型定义

定义系统中的各种权限类型、资源类型等
"""

from enum import Enum
from typing import List, Dict, Any
from dataclasses import dataclass
from datetime import datetime


class PrivilegeType(Enum):
    """权限类型枚举"""
    
    # 全局权限
    CREATE_USER = "CREATE_USER"
    DROP_USER = "DROP_USER"
    CREATE_ROLE = "CREATE_ROLE"
    DROP_ROLE = "DROP_ROLE"
    RELOAD = "RELOAD"
    SHUTDOWN = "SHUTDOWN"
    PROCESS = "PROCESS"
    SUPER = "SUPER"
    ALL_PRIVILEGES = "ALL_PRIVILEGES"
    
    # 数据库权限
    CREATE = "CREATE"
    DROP = "DROP"
    ALTER = "ALTER"
    INDEX = "INDEX"
    REFERENCES = "REFERENCES"
    CREATE_TMP_TABLE = "CREATE_TMP_TABLE"
    LOCK_TABLES = "LOCK_TABLES"
    CREATE_VIEW = "CREATE_VIEW"
    SHOW_VIEW = "SHOW_VIEW"
    
    # 表权限
    SELECT = "SELECT"
    INSERT = "INSERT"
    UPDATE = "UPDATE"
    DELETE = "DELETE"
    TRIGGER = "TRIGGER"
    
    # 特殊权限
    USAGE = "USAGE"  # 数据库连接权限
    GRANT_OPTION = "GRANT_OPTION"  # 授权权限


class ResourceType(Enum):
    """资源类型枚举"""
    GLOBAL = "GLOBAL"
    DATABASE = "DATABASE"
    TABLE = "TABLE"
    COLUMN = "COLUMN"


@dataclass
class UserInfo:
    """用户信息"""
    username: str
    host: str
    password_hash: str
    created_time: datetime
    last_login: datetime = None
    is_active: bool = True
    max_connections: int = 100
    
    def get_user_key(self) -> str:
        """获取用户唯一标识"""
        return f"{self.username}@{self.host}"


@dataclass
class PrivilegeInfo:
    """权限信息"""
    privilege_type: PrivilegeType
    resource_type: ResourceType
    resource_name: str  # 可以是 *, database_name, table_name
    is_grantable: bool = False
    granted_time: datetime = None
    granted_by: str = None
    
    def matches_resource(self, resource_type: ResourceType, resource_name: str) -> bool:
        """检查是否匹配指定资源"""
        if self.resource_type != resource_type:
            return False
        
        # 通配符匹配
        if self.resource_name == "*":
            return True
        
        # 精确匹配
        if self.resource_name == resource_name:
            return True
        
        # 数据库级通配符匹配 (例如: sales_db.*)
        if "." in self.resource_name and self.resource_name.endswith(".*"):
            db_name = self.resource_name[:-2]
            if resource_name.startswith(f"{db_name}."):
                return True
        
        return False


@dataclass
class RoleInfo:
    """角色信息"""
    role_name: str
    description: str
    privileges: List[PrivilegeInfo]
    created_time: datetime
    is_active: bool = True


@dataclass
class PermissionResult:
    """权限检查结果"""
    allowed: bool
    reason: str = ""
    privilege_source: str = ""  # 权限来源（直接权限/角色权限）
    audit_info: Dict[str, Any] = None
    
    def __post_init__(self):
        if self.audit_info is None:
            self.audit_info = {}


# 预定义角色
PREDEFINED_ROLES = {
    "root": RoleInfo(
        role_name="root",
        description="超级管理员，拥有所有权限",
        privileges=[
            PrivilegeInfo(
                privilege_type=PrivilegeType.ALL_PRIVILEGES,
                resource_type=ResourceType.GLOBAL,
                resource_name="*",
                is_grantable=True
            )
        ],
        created_time=datetime.now()
    ),
    
    "db_admin": RoleInfo(
        role_name="db_admin",
        description="数据库管理员",
        privileges=[
            PrivilegeInfo(PrivilegeType.CREATE, ResourceType.GLOBAL, "*"),
            PrivilegeInfo(PrivilegeType.DROP, ResourceType.GLOBAL, "*"),
            PrivilegeInfo(PrivilegeType.ALTER, ResourceType.GLOBAL, "*"),
            PrivilegeInfo(PrivilegeType.INDEX, ResourceType.GLOBAL, "*"),
        ],
        created_time=datetime.now()
    ),
    
    "developer": RoleInfo(
        role_name="developer", 
        description="开发人员",
        privileges=[
            PrivilegeInfo(PrivilegeType.SELECT, ResourceType.GLOBAL, "*"),
            PrivilegeInfo(PrivilegeType.INSERT, ResourceType.GLOBAL, "*"),
            PrivilegeInfo(PrivilegeType.UPDATE, ResourceType.GLOBAL, "*"),
            PrivilegeInfo(PrivilegeType.DELETE, ResourceType.GLOBAL, "*"),
        ],
        created_time=datetime.now()
    ),
    
    "readonly": RoleInfo(
        role_name="readonly",
        description="只读用户",
        privileges=[
            PrivilegeInfo(PrivilegeType.SELECT, ResourceType.GLOBAL, "*"),
        ],
        created_time=datetime.now()
    )
}


# 操作到权限的映射
OPERATION_PRIVILEGE_MAP = {
    "create_database": PrivilegeType.CREATE,
    "drop_database": PrivilegeType.DROP,
    "list_databases": PrivilegeType.USAGE,
    "create_table": PrivilegeType.CREATE,
    "drop_table": PrivilegeType.DROP,
    "select_records": PrivilegeType.SELECT,
    "insert_record": PrivilegeType.INSERT,
    "update_records": PrivilegeType.UPDATE,
    "delete_records": PrivilegeType.DELETE,
    "list_tables": PrivilegeType.SELECT,  # 需要SELECT权限才能看到表
    "get_table_schema": PrivilegeType.SELECT,
    "use_database": PrivilegeType.USAGE,  # 使用数据库需要USAGE权限
    # 用户与授权管理操作
    "create_user": PrivilegeType.CREATE_USER,
    "drop_user": PrivilegeType.DROP_USER,
    "grant_privilege": PrivilegeType.GRANT_OPTION,
    "revoke_privilege": PrivilegeType.GRANT_OPTION,
    "list_users": PrivilegeType.SUPER,
    "get_user_privileges": PrivilegeType.SUPER,
}


def get_required_privilege(operation: str) -> PrivilegeType:
    """根据操作获取所需权限"""
    return OPERATION_PRIVILEGE_MAP.get(operation, PrivilegeType.USAGE)
